﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Surface.Core;
using Microsoft.Surface.Core.Manipulations;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace SurfaceApplication3
{
    class Tower 
    {
        private Texture2D texture;
        private Vector2 position;
        private Vector2 size;
        private Vector2 origin;
        private float rotation;
        private int hitpoints;
        private int shield;
        private List<Bullets> bullets;
        private List<Contact> addedContacts;
        private List<Contact> previousContacts;
        public List<Contact> _previousContacts
        {
            get
            {
                return previousContacts;
            }
        }

        #region ManipulationProperties

        private Affine2DManipulationProcessor manipulationProcessor;
        private bool isManipulating;
        private float manipulationXPoint = 0.0f;
        private float manipulationYPoint = 0.0f;
        private float manipulationScale = 1.0f;
        private float manipulationRotation = 0.0f;

        #endregion


        #region ManipulationEvents
        private void OnAffine2DManipulationStarted(object sender, Affine2DOperationStartedEventArgs e)
        {
            isManipulating = true;
        }

        private void OnAffine2DManipulationCompleted(object sender, Affine2DOperationCompletedEventArgs e)
        {
            isManipulating = false;
        }

        private void OnAffine2DDelta(object sender, Affine2DOperationDeltaEventArgs e)
        {
            // Validate the state.
            //Debug.Assert((this.isManipulating && sender is Affine2DManipulationProcessor));

            // Update manipulation values.
            this.manipulationXPoint += e.DeltaX;
            this.manipulationYPoint += e.DeltaY;
            this.manipulationScale *= e.ScaleDelta;
            this.manipulationRotation += e.RotationDelta;
        }
        #endregion


        public Tower(Texture2D texture,Vector2 position)
        {
            this.texture = texture;
            this.position = position;
            this.size = new Vector2(100, 100);
            this.origin = new Vector2(50,50);
            this.hitpoints = 100;
            this.shield = 0;
            rotation = 0;
            addedContacts = new List<Contact>();
            previousContacts = new List<Contact>();
            #region InitManipulationProcessor

            // Support all manipulation actions.
            /* Affine2DManipulations supportedManipulations =
                 Affine2DManipulations.TranslateX | Affine2DManipulations.TranslateY |
                 Affine2DManipulations.Rotate | Affine2DManipulations.Scale;*/
            Affine2DManipulations supportedManipulations = Affine2DManipulations.Rotate;

            // Create and initialize the manipulation processor with the supported manipulations.
            manipulationProcessor = new Affine2DManipulationProcessor(supportedManipulations);

            // Add handlers for manipulation events.
            manipulationProcessor.Affine2DManipulationStarted +=
                new EventHandler<Affine2DOperationStartedEventArgs>(OnAffine2DManipulationStarted);
            manipulationProcessor.Affine2DManipulationCompleted +=
                new EventHandler<Affine2DOperationCompletedEventArgs>(OnAffine2DManipulationCompleted);
            manipulationProcessor.Affine2DManipulationDelta +=
                new EventHandler<Affine2DOperationDeltaEventArgs>(OnAffine2DDelta);
            #endregion
        }


        public void update(ReadOnlyContactCollection currentContacts)
        {
            // Create a list for removed manipulators.
            List<Manipulator> removedManipulators = new List<Manipulator>();
        
              Contact temp_contact;
            if (previousContacts != null)
            {
                // Find all the contacts that were removed since the last check. 
                foreach (Contact contact in previousContacts)
                {
                    
                    if (currentContacts.TryGetContactFromId(contact.Id, out temp_contact))
                    {
                       // if (!belongs(temp_contact))
                       // {
                            addedContacts.Add(temp_contact);
                        //}
                    }
                    else
                    {
                        removedManipulators.Add(new Manipulator(contact.Id,contact.CenterX,contact.CenterY));
                    }
                }
            }
            
            
            // Create a list for the current manipulators.
            List<Manipulator> currentManipulators = new List<Manipulator>();
           
            //virtual fixed center
            
            if (addedContacts.Count > 0)
            {
                float h = (float)Math.Sqrt((addedContacts.First<Contact>().CenterX - position.X) * (addedContacts.First<Contact>().CenterX - position.X) + (addedContacts.First<Contact>().CenterY - position.Y) * (addedContacts.First<Contact>().CenterY - position.Y));
                float a = (addedContacts.First<Contact>().CenterX - position.X);
                float o = (addedContacts.First<Contact>().CenterY - position.Y);
              
                
                float offsetX = -20*a/h;
                float offsetY = -20*o/h;

                System.Console.WriteLine(addedContacts.First<Contact>().CenterX + " " + (position.X + offsetX)+" " + addedContacts.First<Contact>().CenterY + " " + (position.Y + offsetY));
                currentManipulators.Add(new Manipulator(1, position.X +offsetX, position.Y +offsetY));
            }

            // Transform the current contacts to Manipulators.
            foreach (Contact contact in addedContacts)
            {

                currentManipulators.Add(new Manipulator(contact.Id, contact.CenterX, contact.CenterY));
                //System.Console.Write(contact.Id);
                //System.Console.WriteLine();
            }

            // Save contacts for the next comparison.
            previousContacts = addedContacts;

            if ((currentManipulators.Count > 0) || (removedManipulators.Count > 0))
            {
                // Raise Manipulation events, if appropriate.
                manipulationProcessor.ProcessManipulators(currentManipulators,
                    removedManipulators);
            }
            addedContacts = new List<Contact>();
        }
        

        public void add_contact(Contact item)
        {
            addedContacts.Add(item);
        }

        public bool belongs(Contact contact){

            if ((contact.X - position.X) * (contact.X - position.X) + (contact.Y-position.Y) * (contact.Y-position.Y) < (texture.Height / 2) * (texture.Height / 2))
            {
                return true;
            }else{
                return false;
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, null, Color.White, manipulationRotation, origin, 1, SpriteEffects.None, 1); 
        }

        public void LoadContent(ContentManager content)
        {

        }
    }
}
